package com.magenta.maxoptra.gis;

import com.magenta.maxoptra.gis.commons.Pair;
import com.magenta.maxoptra.gis.commons.Quadruple;

import javax.naming.NamingException;
import java.sql.SQLException;

/*
* Project: MaxOptRA v1.2
* User: Ivan Usalko
* Date: 16.09.2009 18:58:36
*
* Copyright (c) 1999-2009 Magenta Corporation Ltd. All Rights Reserved.
* Magenta Technology proprietary and confidential.
* Use is subject to license terms.
*/
/**
 * Interface RoutesCacheMBean ...
 */
public interface RoutesCacheMBean {

    static final String OBJECT_NAME = "gis-services:service=RoutesCacheMBean";
    static final String JNDI_NAME = "RoutesCacheMBean";

    public String statistics();

    /**
     * Reset persistent cache in initial state.
     * Drop all records and droped their from in memory cache.
     * @return true if operation success.
     */
    public boolean reset() throws NamingException, SQLException, InterruptedException, IllegalAccessException;

    /**
     * Save all not flushed data into db.
     * @return true if operation success.
     */
    public boolean persistAllCaches() throws NamingException, SQLException, InterruptedException, IllegalAccessException;

    /**
     * Minimal count of persists (<code>EntityManager</code>) before flush.
     * @return more then zero;
     */
    public int getMinRecordsBeforeFlush();

    /**
     * Setup size of cache param.
     * @param recordsCount more then zero.
     */
    public void setMinRecordsBeforeFlush(int recordsCount);

    /**
     * Maximal delay in milliseconds after last flush.
     * @return more then zero value.
     */
    public long getMaxDelayAfterLastFlush();

    /**
     * Setup delay after last flush.
     * @param delayInMillis more then zero value;
     */
    public void setMaxDelayAfterLastFlush(long delayInMillis);

    /**
     * Get current local cache size.
     * @return more then zero;
     */
    public int getMaxRecordsInLocalCache();

    /**
     * Set local cache size.
     * @param maxRecordsInLocalCache more then zero.
     */
    public void setMaxRecordsInLocalCache(int maxRecordsInLocalCache);

    /**
     * Default method for JBoss JMX service (call on stop service).
     */
    public void stop();

    /**
     * Default method for JBoss JMX service (call on start service).
     */
    public void start();


    RoutesCache getSegment(GeoProviderSettings settings);

    public static final int DEFAULT_MAX_RECORDS_IN_LOCAL_CACHE = 10000;
    public static final int DEFAULT_MIN_RECORDS_BEFORE_FLUSH = 1000;
    public static final int MSECS_IN_HOUR = 60 * 60 * 1000;
    public static final long DEFAULT_MAX_DELAY_AFTER_LAST_FLUSH = 3 * MSECS_IN_HOUR;

    /**
     * Request route details in persistent state.
     * @param providerName name of external provider for routing info.
     * @param versionApi version API for access to external provider.
     * @param source from location.
     * @param destination to location. @return null if not find.
     */
    @Deprecated
    public Pair<Double, Long> findRoute(String providerName, String versionApi, GeographicCoordinates source, GeographicCoordinates destination);

    /**
     * Try to persist local cache into DB,
     * then clear.
     * Always be synchronized.
     * @return true if success.
     */
    public boolean flushLocalCache() throws NamingException, SQLException, InterruptedException, IllegalAccessException;

    /**
     * Remove request from persisted state of GeoInfo Cache.
     * @param key id of request.
     * @return true if success.
     */
    public boolean removeRouteInfo(RouteRequestRecordPK key);

    /**
     * Put pair key, value into persisted cache.
     * @param pk primary key {@link RouteRequestRecordPK}.
     * @param leg response info.
     */
    void persistRouteInfo(RouteRequestRecordPK pk, Quadruple<Double, Long, Long, Integer> leg) throws NamingException, SQLException, InterruptedException, IllegalAccessException;

    /**
     * Internal method for synchronization between two states in memory and persisted.
     * @param cid unique code @see Apis#cid
     * @param from from location.
     * @param to to location.
     * @return null if not find.
     */
    public Quadruple<Double, Long, Long, Integer> findRouteByCID(Long cid, GeographicCoordinates from,
                                             GeographicCoordinates to);

}